home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / show / mpeg_player122.lha / src / parseblock.c < prev    next >
C/C++ Source or Header  |  1992-12-08  |  9KB  |  438 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #define NO_SANITY_CHECKS
  22. #include <assert.h>
  23. #include "video.h"
  24. #include "decoders.h"
  25.  
  26. /* External declarations. */
  27.  
  28. extern int zigzag_direct[];
  29.  
  30. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  31.  
  32. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  33.  
  34.  
  35. /*
  36.  *--------------------------------------------------------------
  37.  *
  38.  * ParseReconBlock --
  39.  *
  40.  *    Parse values for block structure from bitstream.
  41.  *      n is an indication of the position of the block within
  42.  *      the macroblock (i.e. 0-5) and indicates the type of 
  43.  *      block (i.e. luminance or chrominance). Reconstructs
  44.  *      coefficients from values parsed and puts in 
  45.  *      block.dct_recon array in vid stream structure.
  46.  *      sparseFlag is set when the block contains only one
  47.  *      coeffictient and is used by the IDCT.
  48.  *
  49.  * Results:
  50.  *    
  51.  *
  52.  * Side effects:
  53.  *      Bit stream irreversibly parsed.
  54.  *
  55.  *--------------------------------------------------------------
  56.  */
  57.  
  58. #define DCT_recon blockPtr->dct_recon
  59. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  60. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  61. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  62.  
  63. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  64. #define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
  65.  
  66. int 
  67. ParseReconBlock(n)
  68.      int n;
  69. {
  70.   int sparseFlag;
  71.   unsigned int temp_curBits;
  72.   int temp_bitOffset;
  73.   int temp_bufLength;
  74.   unsigned int *temp_bitBuffer;
  75.   Block *blockPtr = &curVidStream->block;
  76.   
  77.   if (bufLength < 100)
  78.     correct_underflow();
  79.  
  80.   temp_curBits = curBits;
  81.   temp_bitOffset = bitOffset;
  82.   temp_bufLength = bufLength;
  83.   temp_bitBuffer = bitBuffer;
  84.  
  85.   {
  86.  
  87.     register unsigned int curBits;
  88.     register int bitOffset;
  89.     register int bufLength;
  90.     register unsigned int *bitBuffer;
  91.  
  92.     int diff;
  93.     int size, level, i, run, pos;
  94.     short int *reconptr, coeff;
  95.     unsigned char *iqmatrixptr, *niqmatrixptr;
  96.     int qscale;
  97.  
  98.     curBits = temp_curBits;
  99.     bitOffset = temp_bitOffset;
  100.     bufLength = temp_bufLength;
  101.     bitBuffer = temp_bitBuffer;
  102.  
  103.     sparseFlag = 0;
  104.  
  105.     reconptr = DCT_recon[0];
  106.  
  107.     /* 
  108.      * Hand coded version of memset that's a little faster...
  109.      * Old call:
  110.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  111.      */
  112.     {
  113.       int *p;
  114.       p = (int *) reconptr;
  115.       p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] = 
  116.       p[10] = p[11] = p[12] = p[13] = p[14] = p[15] = p[16] = p[17] = p[18] = p[19] =
  117.       p[20] = p[21] = p[22] = p[23] = p[24] = p[25] = p[26] = p[27] = p[28] = p[29] =
  118.       p[30] = p[31] = 0;
  119.     }
  120.  
  121.     if (curVidStream->mblock.mb_intra) {
  122.  
  123.       if (n < 4) {
  124.  
  125.     DecodeDCTDCSizeLum(&size);
  126.  
  127.     if (size != 0) {
  128.       get_bitsn(size, &diff);
  129.           if (!(diff & bitTest[32-size])) {
  130.         diff = rBitMask[size] | (diff + 1);
  131.       }
  132.     }
  133.     else diff = 0;
  134.  
  135.     if (n == 0) {
  136.       coeff = diff << 3;
  137.       if (curVidStream->mblock.mb_address -
  138.           curVidStream->mblock.past_intra_addr > 1) 
  139.         coeff += 1024;
  140.       else coeff += DCT_dc_y_past;
  141.       DCT_dc_y_past = coeff;
  142.  
  143.       *reconptr = coeff;
  144.       sparseFlag++;
  145.  
  146.     }
  147.     else {
  148.       coeff = DCT_dc_y_past + (diff << 3);
  149.  
  150.       *reconptr = coeff;
  151.       sparseFlag++;
  152.  
  153.       DCT_dc_y_past = coeff;
  154.     }
  155.       }
  156.       
  157.       else {
  158.     
  159.     DecodeDCTDCSizeChrom(&size);
  160.     
  161.     if (size != 0) {
  162.       get_bitsn(size, &diff);
  163.           if (!(diff & bitTest[32-size])) {
  164.         diff = rBitMask[size] | (diff + 1);
  165.       }
  166.     }
  167.     else diff = 0;
  168.     
  169.     if (n == 4) {
  170.       coeff = diff << 3;
  171.       if (curVidStream->mblock.mb_address -
  172.           curVidStream->mblock.past_intra_addr > 1) 
  173.         coeff += 1024;
  174.       else coeff += DCT_dc_cr_past;
  175.       DCT_dc_cr_past = coeff;
  176.  
  177.       *reconptr = coeff;
  178.       sparseFlag++;
  179.  
  180.     }
  181.     else {
  182.       coeff = diff << 3;
  183.       if (curVidStream->mblock.mb_address -
  184.           curVidStream->mblock.past_intra_addr > 1) 
  185.         coeff += 1024;
  186.       else coeff += DCT_dc_cb_past;
  187.       DCT_dc_cb_past = coeff;
  188.  
  189.       *reconptr = coeff;
  190.       sparseFlag++;
  191.  
  192.     }
  193.       }
  194.       
  195.       i = 0; pos = 0;
  196.     
  197.       if (curVidStream->picture.code_type != 4) {
  198.     
  199.     qscale = curVidStream->slice.quant_scale;
  200.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  201.     
  202.     while(1) {
  203.       
  204.       DECODE_DCT_COEFF_NEXT(&run, &level);
  205.  
  206.       if (run == END_OF_BLOCK) break;
  207.  
  208.       i = i + run + 1;
  209.  
  210.       pos = zigzag_direct[i];
  211.  
  212.       if (i > 63) {
  213.         goto end;
  214.       }
  215.  
  216.       coeff = (level * qscale * ((int) (*(iqmatrixptr+pos))))
  217.         >> 3;
  218.       if ((coeff & 1) == 0) 
  219.         coeff -= Sign(coeff);
  220.       
  221.       if (coeff > 2047) coeff = 2047;
  222.       else if (coeff < -2048) coeff = -2048;
  223.  
  224.       *(reconptr+pos) = coeff;
  225.       sparseFlag++;
  226.  
  227.     }
  228.  
  229.     /* If only one coefficient, store position + 1 in sparseFlag,
  230.        otherwise reset to zero.
  231.     */
  232.  
  233. #ifdef ANALYSIS 
  234.  
  235.     {
  236.       extern unsigned int *mbCoeffPtr;
  237.       mbCoeffPtr[sparseFlag]++;
  238.     }
  239. #endif
  240.  
  241.     if (sparseFlag == 1) sparseFlag = pos+1;
  242.     else sparseFlag = 0;
  243.  
  244.     flush_bits(2);
  245.     goto end;
  246.       }
  247.     }
  248.     
  249.     else {
  250.       
  251.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  252.       qscale = curVidStream->slice.quant_scale;
  253.       
  254.       DECODE_DCT_COEFF_FIRST(&run, &level);
  255.       i = run;
  256.  
  257.       pos = zigzag_direct[i];
  258.       
  259.       coeff = (((level<<1) + Sign(level)) * qscale * 
  260.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  261.       
  262.       if ((coeff & 1) == 0) 
  263.     coeff -= Sign(coeff);
  264.       
  265.       if (coeff > 2047) coeff = 2047;
  266.       else if (coeff < -2048) coeff = -2048;
  267.  
  268.  
  269.       *(reconptr+pos) = coeff;
  270.       sparseFlag++;
  271.  
  272.       if (curVidStream->picture.code_type != 4) {
  273.     
  274.     while(1) {
  275.       
  276.       DECODE_DCT_COEFF_NEXT(&run, &level);
  277.  
  278.       if (run == END_OF_BLOCK) break;
  279.  
  280.       i = i+run+1;
  281.       
  282.       if (i > 63) {
  283.         goto end;
  284.       }
  285.  
  286.       pos = zigzag_direct[i];
  287.       
  288.       coeff = (((level<<1) + Sign(level)) * qscale * 
  289.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  290.       
  291.       if ((coeff & 1) == 0) 
  292.         coeff -= Sign(coeff);
  293.       
  294.       if (coeff > 2047) coeff = 2047;
  295.       else if (coeff < -2048) coeff = -2048;
  296.       
  297.       *(reconptr+pos) = coeff;
  298.       sparseFlag++;
  299.  
  300.     }
  301.  
  302.     /* If only one coefficient, store which one in sparseFlag,
  303.        otherwise reset to zero.
  304.     */
  305. #ifdef ANALYSIS
  306.     {
  307.       extern unsigned int *mbCoeffPtr;
  308.       mbCoeffPtr[sparseFlag]++;
  309.     }
  310. #endif
  311.  
  312.     if (sparseFlag == 1) sparseFlag = pos+1;
  313.     else sparseFlag = 0;
  314.     
  315.     flush_bits(2);
  316.     goto end;
  317.       }
  318.     }
  319.     
  320.   end:
  321.  
  322.     j_rev_dct(reconptr, sparseFlag);
  323.  
  324.     temp_curBits = curBits;
  325.     temp_bitOffset = bitOffset;
  326.     temp_bufLength = bufLength;
  327.     temp_bitBuffer = bitBuffer;
  328.  
  329.   }
  330.  
  331.   curBits = temp_curBits;
  332.   bitOffset = temp_bitOffset;
  333.   bufLength = temp_bufLength;
  334.   bitBuffer = temp_bitBuffer;
  335.  
  336.   return sparseFlag;
  337. }
  338.     
  339. #undef DCT_recon 
  340. #undef DCT_dc_y_past 
  341. #undef DCT_dc_cr_past 
  342. #undef DCT_dc_cb_past 
  343.  
  344.  
  345. /*
  346.  *--------------------------------------------------------------
  347.  *
  348.  * ParseAwayBlock --
  349.  *
  350.  *    Parses off block values, throwing them away.
  351.  *      Used with grayscale dithering.
  352.  *
  353.  * Results:
  354.  *    None.
  355.  *
  356.  * Side effects:
  357.  *      None.
  358.  *
  359.  *--------------------------------------------------------------
  360.  */
  361.  
  362. int 
  363. ParseAwayBlock(n)
  364.      int n;
  365. {
  366.   unsigned int diff;
  367.   unsigned int size, run;
  368.   int level;
  369.  
  370.   if (bufLength < 100)
  371.     correct_underflow();
  372.  
  373.   if (curVidStream->mblock.mb_intra) {
  374.  
  375.     /* If the block is a luminance block... */
  376.  
  377.     if (n < 4) {
  378.  
  379.       /* Parse and decode size of first coefficient. */
  380.  
  381.       DecodeDCTDCSizeLum(&size);
  382.  
  383.       /* Parse first coefficient. */
  384.  
  385.       if (size != 0) {
  386.     get_bitsn(size, &diff);
  387.       }
  388.     }
  389.  
  390.     /* Otherwise, block is chrominance block... */
  391.  
  392.     else {
  393.  
  394.       /* Parse and decode size of first coefficient. */
  395.  
  396.       DecodeDCTDCSizeChrom(&size);
  397.  
  398.       /* Parse first coefficient. */
  399.  
  400.       if (size != 0) {
  401.     get_bitsn(size, &diff);
  402.       }
  403.     }
  404.   }
  405.  
  406.   /* Otherwise, block is not intracoded... */
  407.  
  408.   else {
  409.  
  410.     /* Decode and set first coefficient. */
  411.  
  412.     DECODE_DCT_COEFF_FIRST(&run, &level);
  413.   }
  414.  
  415.   /* If picture is not D type (i.e. I, P, or B)... */
  416.  
  417.   if (curVidStream->picture.code_type != 4) {
  418.  
  419.     /* While end of macroblock has not been reached... */
  420.  
  421.     while (1) {
  422.  
  423.       /* Get the dct_coeff_next */
  424.  
  425.       DECODE_DCT_COEFF_NEXT(&run, &level);
  426.  
  427.       if (run == END_OF_BLOCK) break;
  428.     }
  429.  
  430.     /* End_of_block */
  431.  
  432.     flush_bits(2);
  433.   }
  434.  
  435.   return PARSE_OK;
  436. }
  437.  
  438.